<?php
/**
 * @subpackage  mars.includes
 *
 * @copyright   Copyright (C) 2013 - 2014 ChinaRoad, Inc. All rights reserved.
 */
defined('_MEXEC') or die;

/**
 * Mars! Application class
 *
 * Provide many supporting API functions
 */
final class Application {

    /**
     * Dispatch the application request to module.
     */
    public function dispatch($module, $path = '', $params = array()) {
        // load modules
        $module_path = MPATH_MODULES . '/mod_' . $module . '/mod_' . $module . '.php';
        if (!file_exists($module_path)){
            $this->return_error(404, 'Module Not Found', 'The requested Module ' . $module . ' not found on this server.');
            exit ();
        }
        require_once $module_path;
        

        $method = strtoupper ( $_SERVER ['REQUEST_METHOD'] );
        $function = '\\modules\\' . $module . '\\' . str_replace('/', '_', $path);
        // check function
        if (!function_exists($function)) {
            $this->return_error(404, 'Not Found', 'The requested Function ' . $function . ' not found on this server.');
            exit ();
        }
        // call function 
        try {
            if (call_user_func($function, $params, $method, $this) === false) {
                $this->return_error(500, 'Internal Server Error', 'The requested Function ' . $function . ' call failed!');
                exit ();
            }            
        } catch (Exception $e) {
            $this->return_error(500, 'Internal Server Error', 'The requested Function ' . $function . ' call failed!');
            exit ();
        }
    }

    /**
     * Check http request method!
     */
    public function require_method($method, $return = true) {
        if (strcasecmp ($method, $_SERVER ['REQUEST_METHOD']) === 0) {
            return true;
        }
        if ($return) {
            $this->return_error(405, 'Method Not Allowed', 'The method is not allowed for Request-URI.');
            exit ();
        } else {
            return false;
        }        
    }

    /**
     * get client's ip
     */
    function client_ip() {
        $ip = '';
        if (isset($HTTP_SERVER_VARS ['HTTP_X_FORWARDED_FOR'])) {
            $ip = $HTTP_SERVER_VARS ['HTTP_X_FORWARDED_FOR'];
        } elseif (isset($HTTP_SERVER_VARS ['HTTP_CLIENT_IP'])) {
            $ip = $HTTP_SERVER_VARS ['HTTP_CLIENT_IP'];
        } elseif (isset($HTTP_SERVER_VARS ['REMOTE_ADDR'])) {
            $ip = $HTTP_SERVER_VARS ['REMOTE_ADDR'];
        } elseif (getenv ( 'HTTP_X_FORWARDED_FOR' )) {
            $ip = getenv ( 'HTTP_X_FORWARDED_FOR' );
        } elseif (getenv ( 'HTTP_CLIENT_IP' )) {
            $ip = getenv ( 'HTTP_CLIENT_IP' );
        } elseif (getenv ( 'REMOTE_ADDR' )) {
            $ip = getenv ( 'REMOTE_ADDR' );
        }
        return $ip;
    }

    /**
     * Find out witch system current application is running.
     */ 
    public function system() {
        switch (true) {
            case stristr(PHP_OS, 'WIN'): return 'Windows';
            case stristr(PHP_OS, 'DAR'): return 'OS X';
            case stristr(PHP_OS, 'LINUX'): return 'Linux';
            default : return 'Unkown';
        }
    }
    
    /**
     * Return json to client 
     * @param data array
     */ 
    public function return_json($data, $code = 200) {
        header('HTTP/1.1 ' . $code);
        header('Content-Type: application/json');
        echo json_encode($data);
    }

    /**
     * Return http error with default templete
     */
    public function return_error($code, $title, $desc = null) {
        header('HTTP/1.1 ' . $code . ' '. $title);
        echo 
        '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">',
        '<html><head>',
        '<title>' , $code , ' ' , $title , '</title>',
        '</head><body>',
        '<h1>', $title , '</h1>';
        if (isset($desc)) echo '<p>' . $desc . ' </p>';
        echo '</body></html>';
    }
    
}